home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_07_07 / v7n7109a.txt < prev    next >
Text File  |  1989-07-24  |  6KB  |  238 lines

  1. /*
  2.  *    Title:         HEAP.C
  3.  *    Name:          Heap library source code
  4.  *    (C) Copyright Avi Farah, 1988.
  5.  */
  6.  
  7.  
  8.  
  9.  
  10. #include <stdio.h>
  11. #include <malloc.h>
  12. #include <time.h>
  13. #include "heap.h"
  14.  
  15.  
  16.  
  17.  
  18. #define  UNDERLINECHAR     '\xdf'
  19. #define  MAKEWORD( ch )    ((unsigned)((char)(ch)) & 0x00FF)
  20.  
  21.  
  22.  
  23.  
  24. static int  iInst = 0;        // Instance of enterence
  25. static char
  26.       *szDebug     = "HEAP.DBG",    // Output file
  27.       *szModeFirst = "w",           // File open modes
  28.       *szModeRest  = "a";
  29.  
  30.  
  31.  
  32.  
  33. /*
  34.  *    Prototypes
  35.  */
  36. static void WriteStatus( int iHeapStatus,  FILE *pDebug );
  37.  
  38.  
  39.  
  40.  
  41. /*****   HeapLOOK   ********************************************************/
  42. /*
  43.  *    Heap Initialization and Look.
  44.  */
  45. void  HeapLOOK( char szFile[],  unsigned uLine,  char cFillChr )
  46.    {
  47.    struct _heapinfo  hinfo;           // A structure defined in malloc.h
  48.    int               iHeapStat;
  49.    FILE              *pDebug;         // Pointer to debug file
  50.    char              *szMode;         // File open mode
  51.  
  52.    /*
  53.     *    Which instance are we running?
  54.     *    First is 0th instance.
  55.     */
  56.    if (iInst == 0)
  57.       szMode = szModeFirst;
  58.    else
  59.       szMode = szModeRest;
  60.  
  61.    /*
  62.     *    Open a dump file
  63.     */
  64.    pDebug = fopen(szDebug, szMode);
  65.    if (pDebug == NULL)   return;
  66.  
  67.    /*
  68.     *    Write Header
  69.     */
  70.    if (iInst == 0)
  71.       {
  72.       time_t   ltime;
  73.       register unsigned lc;      // lc == Loop Control
  74.  
  75.       ++iInst;
  76.       time(<ime);
  77.       putchar('\a');             // beep
  78.       fprintf(pDebug, "\nFile:  %s,\tLine:  %u.\t\t%s", szFile, uLine,
  79.                  ctime(<ime));
  80.       for (lc = 0; lc < 60; ++lc)
  81.          putc(UNDERLINECHAR, pDebug);
  82.       }
  83.    else
  84.       {
  85.       fprintf(pDebug, "\n\nHeapLook  %s[%u]:\n", szFile, uLine);
  86.       }
  87.  
  88.    /*
  89.     *    Do a near heap check
  90.     */
  91.    fputs("\n\n_nheapchk():  ", pDebug);
  92.    iHeapStat = _nheapchk();
  93.    WriteStatus(iHeapStat, pDebug);
  94.  
  95.    /*
  96.     *    Do a far heap check
  97.     */
  98.    fputs("_fheapchk():  ", pDebug);
  99.    iHeapStat = _fheapchk();
  100.    WriteStatus(iHeapStat, pDebug);
  101.  
  102.    /*
  103.     *    Do a near heap set
  104.     */
  105.    fprintf(pDebug, "_nheapset(HEAPSETCHAR = %c [=%X Hex]):  ",
  106.       cFillChr, MAKEWORD(cFillChr));
  107.    iHeapStat = _nheapset(cFillChr);
  108.    WriteStatus(iHeapStat, pDebug);
  109.  
  110.    /*
  111.     *    Do a far heap set
  112.     */
  113.    fprintf(pDebug, "_fheapset(HEAPSETCHAR = %c [=%X Hex]):  ",
  114.       cFillChr, MAKEWORD(cFillChr));
  115.    iHeapStat = _fheapset(cFillChr);
  116.    WriteStatus(iHeapStat, pDebug);
  117.  
  118.    /*
  119.     *    Do a near heap walk
  120.     */
  121.    fputs("nheapwalk:  \n", pDebug);
  122.    hinfo._pentry = NULL;
  123.    while ((iHeapStat = _nheapwalk(&hinfo)) == _HEAPOK)
  124.       {
  125.       fprintf(
  126.          pDebug,
  127.          "%6s block at %p of size %4.4X(Hex) == %6.6u\n",
  128.          (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  129.          hinfo._pentry,
  130.          hinfo._size, hinfo._size
  131.              );
  132.       }
  133.    WriteStatus(iHeapStat, pDebug);
  134.  
  135.    /*
  136.     *    Do a far heap walk
  137.     */
  138.    fputs("fheapwalk:  \n", pDebug);
  139.    hinfo._pentry = NULL;
  140.    while ((iHeapStat = _fheapwalk(&hinfo)) == _HEAPOK)
  141.       {
  142.       fprintf(
  143.          pDebug,
  144.          "%6s block at %p of size %4.4X(Hex) == %6.6u\n",
  145.          (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  146.          hinfo._pentry,
  147.          hinfo._size, hinfo._size
  148.  
  149.             );
  150.       }
  151.    WriteStatus(iHeapStat, pDebug);
  152.  
  153.    /*
  154.     *    Close Dump file
  155.     */
  156.    fclose(pDebug);
  157.    }   /* HeapLOOK */
  158.  
  159.  
  160.  
  161.  
  162. /*****   WriteStatus   *****************************************************/
  163.  
  164. static void  WriteStatus( int iHeapStatus,  FILE *pDebug )
  165.    {
  166.    static char
  167.       *szHeapOKMsg      = "OK - heap is fine\n\n",
  168.       *szHeapEmptyMsg   = "OK - heap is empty\n\n",
  169.       *szHeapBadPtrMsg  = "ERROR - Entry field of the entry structure does\n"
  170.                           "       not contain a valid pointer to the heaap\n\n",
  171.       *szHeapBadBeginMsg= "ERROR - The initial header information was not\n"
  172.                           "        found or it was invalid.\n\n",
  173.       *szHeapBadNodeMsg = "ERROR - bad node in heap was found or heap\n"
  174.                           "        is damaged.\n\n",
  175.       *szHeapEndMsg     = "The end of the heap was reached successfully.\n\n";
  176.  
  177.    switch(iHeapStatus)
  178.       {
  179.       case _HEAPOK:        fputs(szHeapOKMsg,       pDebug);   break;
  180.       case _HEAPEMPTY:     fputs(szHeapEmptyMsg,    pDebug);   break;
  181.       case _HEAPBADPTR:    fputs(szHeapBadPtrMsg,   pDebug);   break;
  182.       case _HEAPBADBEGIN:  fputs(szHeapBadBeginMsg, pDebug);   break;
  183.       case _HEAPBADNODE:   fputs(szHeapBadNodeMsg,  pDebug);   break;
  184.       case _HEAPEND:       fputs(szHeapEndMsg,      pDebug);   break;
  185.       }   /* switch */
  186.    }   /* WriteStatus */
  187.  
  188.  
  189.  
  190.  
  191. /*****   MemTrace   ********************************************************/
  192.  
  193. void  MemTrace( char szFile[],  unsigned uLine )
  194.    {
  195.    FILE     *pDebug;
  196.    size_t   stHeap, stStack;  // stack and heap sizes respectively
  197.  
  198.    /*
  199.     *    Open dump file
  200.     */
  201.    pDebug = fopen(szDebug, iInst == 0 ? szModeFirst : szModeRest);
  202.    if (pDebug == NULL)
  203.       {
  204.       fprintf(stderr, "File %s cannot open for debugging.\n", szDebug);
  205.       perror("");
  206.       return;
  207.       }
  208.  
  209.    /*
  210.     *    Write header
  211.     */
  212.    if (iInst == 0)
  213.       {
  214.       time_t   ltime;
  215.       register unsigned lc;
  216.  
  217.       ++iInst;
  218.       time(<ime);
  219.       putchar('\a');             // beep
  220.       fprintf(pDebug, "\nFile:  %s,\tLine:  %u.\t\t%s", szFile, uLine,
  221.                          ctime(<ime));
  222.       for (lc = 0; lc < 60; ++lc)
  223.          putc(UNDERLINECHAR, pDebug);
  224.       fputs("\n\n", pDebug);
  225.       }
  226.  
  227.    stHeap  = _memavl();
  228.    stStack = stackavail();
  229.    fprintf(pDebug, "%s[%u]:  Near Heap=%u [=%X(Hex)],  Stack=%u [=%X(Hex)]\n",
  230.       szFile, uLine, stHeap, stHeap, stStack, stStack);
  231.  
  232.    /*
  233.     *    Close Dubmp file
  234.     */
  235.    if (EOF == fclose(pDebug))
  236.       fprintf(stderr, "Cannot close debugging file %s\n", szDebug);
  237.    }   /* MemTrace */
  238.